NumPy的核心优势在于其强大的向量化运算能力。
与Python循环相比,NumPy运算在底层使用优化的C/Fortran代码,可以提供数十倍甚至上百倍的性能提升。
在金融大数据处理中,向量化运算是必须掌握的核心技能。
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import numpy as np # 导入NumPy数值计算库
# 已知数据
stock_p=np.array([4.98,5.02,4.95,4.91,4.98,4.92,4.88,4.92,4.88,4.82,4.85,4.89,4.91,4.86,4.84,4.92,5.01,5.04])
# 创建NumPy数组stock_return
stock_return=np.array([-0.7968,1.4141,0.8147,-1.4056,1.2195,0.8197,-0.813,0.8197,1.2448,-0.6186,-0.818,-0.4073,1.0288,0.4132,-1.626,-1.7964,-0.5952,-1.5625])
# 1. 计算股票的最高价并输出
p_max=stock_p.max()
print(f"中国建筑8月最高股价为{p_max}") # 输出中国建筑8月最高股价为
# 2. 计算股票的平均涨跌幅,使用round()函数保留三位小数并输出
return_avg=stock_return.mean().round(3)
print(f"平均涨跌幅为{return_avg}") # 输出平均涨跌幅为
# 3. 计算股票涨跌幅的方差和标准差,使用round()函数并保留3位小数
return_var=stock_return.var().round(3)
return_std=stock_return.std().round(3) # 计算标准差并四舍五入
print(f"涨跌幅的方差{return_var},标准差{return_std}") # 输出涨跌幅的方差中国建筑8月最高股价为5.04
平均涨跌幅为-0.148
涨跌幅的方差1.169,标准差1.081
| 方法 | 功能 | 等价写法 |
|---|---|---|
.max() |
最大值 | np.max(arr) |
.min() |
最小值 | np.min(arr) |
.mean() |
算术平均 | np.mean(arr) |
.var() |
方差 | np.var(arr) |
.std() |
标准差 | np.std(arr) |
.round(n) |
四舍五入到n位 | np.round(arr, n) |
方差衡量数据偏离均值的程度:
\[ \large{ \text{Var} = \frac{1}{n} \sum_{i=1}^{n}(x_i - \bar{x})^2 } \]
标准差是方差的平方根,与原始数据同单位:
\[ \large{ \text{Std} = \sqrt{\text{Var}} } \]
ddof=0(总体方差),金融分析常用 ddof=1(样本方差)axis参数决定沿哪个方向聚合计算:
axis=0:垂直方向(跨行),对每列计算axis=1:水平方向(跨列),对每行计算axis=None:对所有元素计算(默认)金融场景对应:
axis=0:多只股票同一时间的市场平均表现axis=1:单只股票的时间序列特征import numpy as np
# 3只股票 × 4个交易日的收益率矩阵
returns = np.array([
[0.05, 0.03, -0.02, 0.04], # 股票A
[0.02, 0.01, 0.03, -0.01], # 股票B
[-0.01, 0.02, 0.01, 0.05] # 股票C
])
# axis=0:跨行计算 → 每日市场平均收益率
daily_avg = returns.mean(axis=0)
print(f'每日平均收益率: {daily_avg}')
# axis=1:跨列计算 → 每只股票平均收益率
stock_avg = returns.mean(axis=1)
print(f'每只股票平均收益率: {stock_avg}')每日平均收益率: [0.02 0.02 0.00666667 0.02666667]
每只股票平均收益率: [0.025 0.0125 0.0175]
cumsum(axis=1):沿行方向逐步累加NumPy支持元素级的算术运算,这是向量化的核心。
| 运算符 | NumPy函数 | 描述 |
|---|---|---|
+ |
np.add |
加法 |
- |
np.subtract |
减法 |
* |
np.multiply |
乘法 |
/ |
np.divide |
除法 |
** |
np.power |
幂运算 |
两个数组形状必须相同,或满足广播规则。
调整后价格: [11 22 33 44 55]
价格变化: [10 10 10 10]
持仓价值: [1000 4000 4500]
简单收益率: [1. 0.5 0.33333333 0.25 ]
对数收益率公式:
\[ \large{ r_{log} = \ln\left(\frac{P_t}{P_{t-1}}\right) = \ln(P_t) - \ln(P_{t-1}) } \]
\[ \large{ r_{log,1 \to 3} = r_{log,1 \to 2} + r_{log,2 \to 3} } \]
对称性:正负收益对称(-50%和+50%的对数收益率绝对值相等)
正态性:更接近正态分布,便于统计建模
应用场景:连续复利模型、Black-Scholes期权定价
# 4只股票的年化收益率
annual_returns = np.array([0.05, 0.06, 0.04, 0.07])
# 指数函数:连续复利计算5年累计收益率
cumulative_5yr = np.exp(annual_returns * 5) - 1
print(f'5年累计收益率: {cumulative_5yr}')
# 波动率计算
volatility = np.std(annual_returns)
variance = volatility ** 2
print(f'波动率: {volatility:.4f}')
print(f'方差: {variance:.4f}')5年累计收益率: [0.28402542 0.34985881 0.22140276 0.41906755]
波动率: 0.0112
方差: 0.0001
| 函数 | 功能 | 金融应用 |
|---|---|---|
np.floor() |
向下取整 | 保守估计所需资金 |
np.ceil() |
向上取整 | 确保资金充足 |
np.round() |
四舍五入 | 报价、结果展示 |
import numpy as np
# 中国建筑8月股价数据(18个交易日)
stock_p = np.array([4.98, 5.02, 4.95, 4.91, 4.98, 4.92, 4.88, 4.92,
4.88, 4.82, 4.85, 4.89, 4.91, 4.86, 4.84, 4.92,
5.01, 5.04])
# 计算日收益率
daily_returns = (stock_p[1:] - stock_p[:-1]) / stock_p[:-1]
# 基本统计量
mean_return = daily_returns.mean()
std_return = daily_returns.std()
# 年化波动率 = 日波动率 × √252
annualized_vol = std_return * np.sqrt(252)
print('=' * 50)
print('中国建筑8月风险收益分析')
print('=' * 50)
print(f'日平均收益率: {mean_return:.4%}')
print(f'日收益率标准差: {std_return:.4%}')
print(f'年化波动率: {annualized_vol:.4%}')==================================================
中国建筑8月风险收益分析
==================================================
日平均收益率: 0.0761%
日收益率标准差: 1.0575%
年化波动率: 16.7876%
# 价格统计
max_price = stock_p.max()
min_price = stock_p.min()
price_range = max_price - min_price
print(f'最高价: {max_price:.2f}元')
print(f'最低价: {min_price:.2f}元')
print(f'价格区间: {price_range:.2f}元')
# 下行风险:只考虑下跌日
downside_returns = daily_returns[daily_returns < 0]
downside_risk = downside_returns.std() * np.sqrt(252)
print(f'下行波动率: {downside_risk:.4%}')
# 夏普比率(假设无风险利率3%)
sharpe_ratio = (mean_return * 252 - 0.03) / annualized_vol
print(f'夏普比率: {sharpe_ratio:.2f}')最高价: 5.04元
最低价: 4.82元
价格区间: 0.22元
下行波动率: 4.6681%
夏普比率: 0.96
夏普比率衡量每承担1单位风险获得的超额收益:
\[ \large{ \text{Sharpe} = \frac{R_p - R_f}{\sigma_p} } \]
| 夏普比率 | 评价 |
|---|---|
| > 1 | 优秀 |
| 0.5 ~ 1 | 良好 |
| 0 ~ 0.5 | 一般 |
| < 0 | 较差(回报低于无风险利率) |
import numpy as np
# 两个投资组合的持仓
portfolio_a = np.array(['600519.SH', '000858.SZ', '600036.SH', '000002.SZ'])
portfolio_b = np.array(['600036.SH', '601318.SH', '000858.SZ', '600000.SH'])
# 交集:共同持仓
common = np.intersect1d(portfolio_a, portfolio_b)
print(f'共同持仓: {common}')
# 并集:所有股票(去重)
all_stocks = np.union1d(portfolio_a, portfolio_b)
print(f'所有股票: {all_stocks}')
# 差集:独有持仓
unique_a = np.setdiff1d(portfolio_a, portfolio_b)
unique_b = np.setdiff1d(portfolio_b, portfolio_a)
print(f'A组合独有: {unique_a}')
print(f'B组合独有: {unique_b}')共同持仓: ['000858.SZ' '600036.SH']
所有股票: ['000002.SZ' '000858.SZ' '600000.SH' '600036.SH' '600519.SH' '601318.SH']
A组合独有: ['000002.SZ' '600519.SH']
B组合独有: ['600000.SH' '601318.SH']
| 函数 | 功能 | 金融应用 |
|---|---|---|
np.intersect1d |
交集 | 找出共同持仓 |
np.union1d |
并集 | 构建完整股票池 |
np.setdiff1d |
差集 | 识别独有持仓 |
>, <, >=, <=, ==, !=)返回布尔数组True 位置的元素逻辑运算符:
| 运算符 | 含义 | 说明 |
|---|---|---|
& |
逻辑与(AND) | 两个条件都满足 |
\| |
逻辑或(OR) | 至少一个条件满足 |
~ |
逻辑非(NOT) | 条件取反 |
注意:条件表达式必须加括号,因为位运算符优先级高于比较运算符。
排序后: [-0.02 -0.01 0.03 0.04 0.05 0.07]
排序索引: [1 4 2 5 0 3]
按索引重建: [-0.02 -0.01 0.03 0.04 0.05 0.07]
np.sort():返回新数组,原数组不变.sort():原地排序,直接修改原数组np.argsort():返回排序后的索引最大值位置: 3, 值: 0.07
最小值位置: 1, 值: -0.02
负收益调整为0: [0.05 0. 0.03 0.07 0. 0.04]
np.argmax() / np.argmin():返回极值的索引位置np.where(条件, True值, False值):条件替换import numpy as np
import time
n = 1000000
arr1 = np.random.randn(n)
arr2 = np.random.randn(n)
# Python循环
start = time.time()
result_slow = []
for i in range(n):
result_slow.append(arr1[i] + arr2[i])
slow_time = time.time() - start
# NumPy向量化
start = time.time()
result_fast = arr1 + arr2
fast_time = time.time() - start
print(f'循环时间: {slow_time:.4f}秒')
print(f'向量化时间: {fast_time:.4f}秒')
print(f'加速比: {slow_time/fast_time:.1f}倍')循环时间: 0.2197秒
向量化时间: 0.0013秒
加速比: 175.7倍
使用向量化运算:避免Python for 循环,直接用NumPy运算符
就地操作节省内存:
| 类别 | 核心函数 | 金融应用 |
|---|---|---|
| 统计运算 | mean, std, var, max, min |
收益率、波动率 |
| 数学函数 | log, exp, sqrt, abs |
对数收益率、复利 |
| 集合运算 | intersect1d, union1d, setdiff1d |
组合分析 |
| 比较与索引 | >, <, &, \|, 布尔索引 |
条件筛选 |
| 排序与搜索 | sort, argsort, argmax, where |
排名、止损 |
| 性能优化 | 向量化、就地操作、预分配 | 大数据处理 |
[商业大数据分析与应用]